package com.gpframework.module.base.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.common.constant.BrandConstants;
import com.gpframework.common.constant.CacheConstants;
import com.gpframework.common.constant.Constants;
import com.gpframework.common.core.redis.RedisCache;
import com.gpframework.common.enums.StoreSysConfig;
import com.gpframework.common.exception.BaseException;
import com.gpframework.common.utils.DateUtils;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.module.base.domain.BaseStoreConfig;
import com.gpframework.module.base.domain.req.BaseStoreConfigAdd;
import com.gpframework.module.base.domain.req.BaseStoreConfigReq;
import com.gpframework.module.base.domain.req.BaseStoreConfigUpdate;
import com.gpframework.module.base.domain.vo.BaseStoreConfigVo;
import com.gpframework.module.base.mapper.BaseStoreConfigMapper;
import com.gpframework.module.base.service.IBaseStoreConfigService;
import com.gpframework.module.common.domain.CommonStoreConfigValue;
import com.gpframework.module.common.domain.req.CommonStoreConfigValueAdd;
import com.gpframework.module.common.domain.req.CommonStoreConfigValueReq;
import com.gpframework.module.common.domain.vo.CommonStoreConfigValueVo;
import com.gpframework.module.common.service.ICommonStoreConfigValueService;
import com.gpframework.module.module.domain.BrandStore;
import com.gpframework.module.pay.utils.joinpay.sdk.utitls.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName BaseStoreConfig
 * @Author gpframework
 * @Date 2022-04-06
 * @Version 1.0.0
 * @Description 店铺基础配置（折扣、手续费等）Service业务层处理
 */
@Service
public class BaseStoreConfigServiceImpl extends ServiceImpl<BaseStoreConfigMapper, BaseStoreConfig> implements IBaseStoreConfigService {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RedisCache redisCache;

    /**
     * 店铺基础配置值持久层接口
     */
    @Autowired
    private ICommonStoreConfigValueService commonStoreConfigValueService;



    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2022-04-06
     * @Param [lqw]
     * @Return List<BaseStoreConfigVo>
     */
    @Override
    public List<BaseStoreConfigVo> listVo(QueryWrapper<BaseStoreConfig> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2022-04-06
     * @Param [id]
     * @Return BaseStoreConfigVo
     */
    @Override
    public BaseStoreConfigVo getVoById(Long id) {
        BaseStoreConfigVo baseStoreConfigVo = this.baseMapper.getVo(id);
        if (StringUtil.isEmpty(baseStoreConfigVo)) {
            return baseStoreConfigVo;
        }
        QueryWrapper<BaseStoreConfig> lqw = new QueryWrapper<>();
        lqw.eq("pid", id);
        List<BaseStoreConfigVo> children = this.baseMapper.listVo(lqw);
        if (StringUtil.isNotEmpty(children) && children.size() > 0) {
            baseStoreConfigVo.setChildren(children);
        }
        return baseStoreConfigVo;
    }


    /**
     * 获取门店基础配置
     *
     * @param baseStoreConfigReq
     * @return
     */
    @Override
    public List<BaseStoreConfigVo> getList(BaseStoreConfigReq baseStoreConfigReq) {
        List<BaseStoreConfigVo> baseStoreConfigList;
        // 从缓存中获取门店基础配置
        String baseStoreConfigKey = Constants.BASE_STORE_CONFIG_KEY + baseStoreConfigReq.getStoreId();
        String baseStoreConfigString = redisCache.getCacheObject(baseStoreConfigKey);
        if (StringUtils.isNotBlank(baseStoreConfigString)) {
            baseStoreConfigList = JSONArray.parseArray(baseStoreConfigString, BaseStoreConfigVo.class);
        } else {
            baseStoreConfigReq.setKey(null);
            // 如果没有缓存，则从数据库中获取，再保存到缓存中
            baseStoreConfigList = this.baseMapper.getList(baseStoreConfigReq);
            //时间返回数组格式
            baseStoreConfigList.stream().filter(e -> StoreSysConfig.BUSINESS_HOURS.name().equals(e.getKey()) && StringUtils.isNotBlank(e.getValue())).forEach(item -> item.setValueList(Arrays.asList(item.getValue().split("-"))));
            String jsonString = JSONArray.toJSONString(baseStoreConfigList);
            redisCache.setCacheObject(baseStoreConfigKey, jsonString);
            redisCache.expire(baseStoreConfigKey, CacheConstants.CACHE_OVERDUE_TWO_HOURS);
        }
        return baseStoreConfigList;
    }

    /**
     * 更新门店配置
     *
     * @param storeConfigValueList
     * @return
     */
    @Override
    @Transactional
    public boolean updateStoreConfig(List<CommonStoreConfigValue> storeConfigValueList) {
        Long storeId = storeConfigValueList.get(0).getStoreId();
        commonStoreConfigValueService.delByStoreId(storeId);
        storeConfigValueList.forEach(item -> commonStoreConfigValueService.save(item));
        // 删除原有的门店配置缓存记录
        String baseStoreConfigKey = Constants.BASE_STORE_CONFIG_KEY + storeId;
        redisCache.deleteGroupObject(baseStoreConfigKey);
        return true;
    }

    /**
     * 更新门店配置
     *
     * @param brandId
     * @param storeConfigValueAddList
     * @return
     */
    @Override
    @Transactional
    public boolean updateStoreConfig(Long brandId, List<CommonStoreConfigValueAdd> storeConfigValueAddList) {
        Long storeId = storeConfigValueAddList.get(0).getStoreId();
        // 删除原有的门店配置记录
        commonStoreConfigValueService.delByStoreId(storeId);
        // 删除原有的门店配置缓存记录
        String baseStoreConfigKey = Constants.BASE_STORE_CONFIG_KEY + storeId;
        redisCache.deleteGroupObject(baseStoreConfigKey);
        // 保存新的门店配置记录
        storeConfigValueAddList.forEach(item -> {
            item.setBrandId(brandId);
            if (StoreSysConfig.WHETHER_TO_OPEN_THE_COURSE_ADMISSION_OFF.toString().equals(item.getKey())) {
                BaseStoreConfigVo storeConfigValueVo = this.baseMapper.getVo(Long.parseLong(item.getValue()));
                if (StringUtil.isEmpty(storeConfigValueVo)) {
                    throw new BaseException("业务参数不存在");
                }
//                if (StoreSysConfig.NO.getKey().equals(storeConfigValueVo.getKey())) {
//                    CourseInfoReq courseInfoReq = new CourseInfoReq();
//                    courseInfoReq.setBrandId(brandId);
//                    courseInfoReq.setStoreId(item.getStoreId());
//                    boolean isBandRegion = courseInfoService.checkCourseBandRegion(courseInfoReq);
//                    if (isBandRegion) {
//                        throw new BaseException("已有课程绑定场地，请去除后再试关闭课程入场");
//                    }
//                }
            }
            CommonStoreConfigValue storeConfigValue = Convert.convert(new TypeReference<CommonStoreConfigValue>() {
            }, item);
            commonStoreConfigValueService.save(storeConfigValue);
        });
        redisCache.deleteGroupObject(baseStoreConfigKey);
        return true;
    }


    /**
     * 获取配置
     *
     * @param storeConfigValueReq
     * @return
     */
    @Override
    public BaseStoreConfigVo getInfo(CommonStoreConfigValueReq storeConfigValueReq) {
        BaseStoreConfigVo baseStoreConfigVo = null;
        // 从缓存中获取配置
        String baseStoreConfigKey = Constants.BASE_STORE_CONFIG_KEY + storeConfigValueReq.getStoreId() + CacheConstants.PACKET_IDENTIFICATION + storeConfigValueReq.getKey();
        baseStoreConfigVo = redisCache.getCacheObject(baseStoreConfigKey);
        if (baseStoreConfigVo == null) {
            // 如果没有缓存，则从数据库中获取
            baseStoreConfigVo = this.baseMapper.getInfo(storeConfigValueReq);
            if (StringUtil.isEmpty(baseStoreConfigVo)) {
                return baseStoreConfigVo;
            }
            redisCache.setCacheObject(baseStoreConfigKey, baseStoreConfigVo);
            redisCache.expire(baseStoreConfigKey, CacheConstants.CACHE_OVERDUE_TWO_HOURS);
        }
        return baseStoreConfigVo;
    }

    /**
     * 初始化门店业务参数
     *
     * @param brandStore
     * @return
     */
    @Override
    public boolean initializeStoreConfig(BrandStore brandStore) {
        if (StringUtil.isEmpty(brandStore) || StringUtil.isEmpty(brandStore.getBrandId()) || StringUtil.isEmpty(brandStore.getStoreId())) {
            logger.info("---------门店信息为空" + brandStore + "---------");
            return false;
        }
        // 删除原有的门店配置记录
        commonStoreConfigValueService.delByStoreId(brandStore.getStoreId());
        //门店业务选项
//        List<BaseStoreConfigVo> baseStoreConfigVoList = this.baseMapper.listVo(new QueryWrapper<>());
        //分组后门店业务选项
//        List<BaseStoreConfigVo> storeConfigVoList = baseStoreConfigVoList.stream().filter(m -> m.getPid() == 0).peek((m) -> m.setChildren(getChildrenList(m, baseStoreConfigVoList))).collect(Collectors.toList());
        //设置默认值
        /*storeConfigVoList.forEach(baseStoreConfigVo -> {
            //门店所选参数实体类
            CommonStoreConfigValue storeConfigValue = Convert.convert(new TypeReference<CommonStoreConfigValue>() {
            }, baseStoreConfigVo);
            storeConfigValue.setBrandId(brandStore.getBrandId());
            storeConfigValue.setBrandName(brandStore.getBrandName());
            storeConfigValue.setStoreId(brandStore.getStoreId());
            storeConfigValue.setStoreName(brandStore.getStoreName());
            storeConfigValue.setBaseStoreConfigTopic(baseStoreConfigVo.getContent());
            //单选框
            if (BrandConstants.INPUT_TYPE_RADIO.equals(baseStoreConfigVo.getInputType())) {
                if (StringUtil.isEmpty(baseStoreConfigVo.getChildren()) || baseStoreConfigVo.getChildren().size() <= 0) {
                    return;
                }
                //默认选项id
                storeConfigValue.setValue(baseStoreConfigVo.getChildren().get(0).getBaseStoreConfigId().toString());
                //乐刷默认值
                if (StoreSysConfig.LESHUA_PAY_FLAG.toString().equals(storeConfigValue.getKey())) {
                    //选项
                    for (BaseStoreConfigVo child : baseStoreConfigVo.getChildren()) {
                        if (!StoreSysConfig.NO.getKey().equals(child.getKey())) {
                            continue;
                        }
                        storeConfigValue.setValue(child.getBaseStoreConfigId().toString());
                    }
                }
            }
            //输入框
            if (BrandConstants.INPUT_TYPE_INPUT.equals(baseStoreConfigVo.getInputType())) {
                //默认值
                storeConfigValue.setValue("0");
            }

            //时间输入框
            if (BrandConstants.INPUT_TYPE_DATE.equals(baseStoreConfigVo.getInputType())) {
                //默认值
                if (StoreSysConfig.BUSINESS_HOURS_START.toString().equals(baseStoreConfigVo.getKey()))
                    storeConfigValue.setValue(BrandConstants.BUSINESS_HOURS_START);
                if (StoreSysConfig.BUSINESS_HOURS_END.toString().equals(baseStoreConfigVo.getKey()))
                    storeConfigValue.setValue(BrandConstants.BUSINESS_HOURS_END);
            }


            if (StringUtil.isEmpty(storeConfigValue.getValue())) {
                return;
            }
            //品牌菜单控制
            if (StoreSysConfig.SYS_BRAND_MENU.toString().equals(baseStoreConfigVo.getKey())) {
                return;
            }
            CommonStoreConfigValueReq storeConfigValueReq = new CommonStoreConfigValueReq();
            storeConfigValueReq.setBrandId(brandStore.getBrandId());
            storeConfigValueReq.setStoreId(brandStore.getStoreId());
            storeConfigValueReq.setKey(baseStoreConfigVo.getKey());
            //是否有业务参数
            CommonStoreConfigValueVo storeConfigValueVo = commonStoreConfigValueMapper.getKey(storeConfigValueReq);
            //业务参数已存在
            if (StringUtil.isNotEmpty(storeConfigValueVo)) {
                return;
            }
            commonStoreConfigValueMapper.insert(storeConfigValue);
        });*/
        QueryWrapper<CommonStoreConfigValue> lqw = new QueryWrapper<>();
        lqw.eq("brand_id", BrandConstants.DEFAULT_BRAND_ID);
        lqw.eq("store_id", BrandConstants.DEFAULT_BRAND_ID);
        lqw.eq("del_status", Constants.DEL_STATUS_FALSE);
        List<CommonStoreConfigValueVo> commonStoreConfigValueVoList = commonStoreConfigValueService.listVo(lqw);
        for (CommonStoreConfigValueVo commonStoreConfigValueVo : commonStoreConfigValueVoList) {
            commonStoreConfigValueVo.setStoreConfigValueId(null);
            commonStoreConfigValueVo.setBrandId(brandStore.getBrandId());
            commonStoreConfigValueVo.setStoreId(brandStore.getStoreId());
        }
        List<CommonStoreConfigValue> storeConfigValueList = Convert.convert(new TypeReference<List<CommonStoreConfigValue>>() {
        }, commonStoreConfigValueVoList);
        commonStoreConfigValueService.saveBatch(storeConfigValueList);
        return true;
    }

    /**
     * 获取目录树
     *
     * @param baseStoreConfigVo
     * @param all
     * @return
     */
    private List<BaseStoreConfigVo> getChildrenList(BaseStoreConfigVo baseStoreConfigVo, List<BaseStoreConfigVo> all) {
        List<BaseStoreConfigVo> children = all.stream().filter(m -> {
            return Objects.equals(m.getPid(), baseStoreConfigVo.getBaseStoreConfigId());
        }).peek(
                (m) -> m.setChildren(getChildrenList(m, all))
        ).collect(Collectors.toList());
        return children;
    }

    /**
     * 修改业务参数
     *
     * @param storeConfigUpdate
     * @return
     */
    @Override
    public boolean edit(BaseStoreConfigUpdate storeConfigUpdate) {
        BaseStoreConfig storeConfig = Convert.convert(new TypeReference<BaseStoreConfig>() {
        }, storeConfigUpdate);
        this.baseMapper.updateById(storeConfig);
        //子集
        List<BaseStoreConfig> children = storeConfigUpdate.getChildren();
        if (StringUtil.isNotEmpty(children) && children.size() > 0) {
            this.updateBatchById(children);
        }
        redisCache.deleteGroupObject(Constants.BASE_STORE_CONFIG_KEY);
        return true;
    }

    /**
     * 新增业务参数
     *
     * @param storeConfigAdd
     * @return
     */
    @Override
    public boolean add(BaseStoreConfigAdd storeConfigAdd) {
        BaseStoreConfig storeConfig = Convert.convert(new TypeReference<BaseStoreConfig>() {
        }, storeConfigAdd);
        this.baseMapper.insert(storeConfig);
        Long baseStoreConfigId = storeConfig.getBaseStoreConfigId();
        List<BaseStoreConfig> children = storeConfigAdd.getChildren();
        for (BaseStoreConfig child : children) {
            child.setPid(baseStoreConfigId);
            this.baseMapper.insert(child);
        }
        redisCache.deleteGroupObject(Constants.BASE_STORE_CONFIG_KEY);
        return true;
    }

    /**
     * 删除业务参数
     *
     * @param storeConfigIds
     * @return
     */
    @Override
    public boolean delByIds(List<Long> storeConfigIds) {
        //删除一级
        this.removeByIds(storeConfigIds);
        UpdateWrapper<BaseStoreConfig> lqw;
        for (Long storeConfigId : storeConfigIds) {
            lqw = new UpdateWrapper<>();
            lqw.set(true, "del_status", Constants.DEL_STATUS_TRUE);
            lqw.eq("pid", storeConfigId);
            this.remove(lqw);
        }
        return true;
    }

    /**
     * 校验课程开始时间
     *
     * @param storeConfigValueReq 业务参数
     * @param courseTime          课程时间
     * @return
     */
    @Override
    public boolean checkStartCourseTime(CommonStoreConfigValueReq storeConfigValueReq, Date courseTime) {
        // 查询业务参数(没设置默认0)
        int hours = 0;
        BaseStoreConfigVo baseStoreConfigVo = this.getInfo(storeConfigValueReq);
        logger.info("----------业务参数：【{}】----------", baseStoreConfigVo);
        //未设置则不校验
        if (StringUtil.isEmpty(baseStoreConfigVo.getValue())) {
            return true;
        }
        if (StringUtil.isNotEmpty(baseStoreConfigVo.getValue())) {
            hours = Integer.parseInt(baseStoreConfigVo.getValue());
        }
        // 距离开课多少小时不允许取消预约。
        Date afterMinute = DateUtils.getAfterHour(courseTime, -hours);
        if (courseTime != null && new Date().getTime() > afterMinute.getTime()) {
            throw new BaseException("距离开课" + hours + "小时不允许取消预约");
        }
        return true;
    }

    /**
     * 获取门店打卡积分配置
     *
     * @param storeId
     * @return
     */
    @Override
    public Long giveIntegralConfig(Long storeId) {
        CommonStoreConfigValueReq storeConfigValueReq = new CommonStoreConfigValueReq();
        storeConfigValueReq.setStoreId(storeId);
        storeConfigValueReq.setKey(StoreSysConfig.PUNCH_THE_CLOCK_INTEGRAL.toString());
        BaseStoreConfigVo baseStoreConfigVo = this.getInfo(storeConfigValueReq);
        if (!org.springframework.util.StringUtils.isEmpty(baseStoreConfigVo) && StringUtils.isNotEmpty(baseStoreConfigVo.getValue())) {
            return Long.valueOf(baseStoreConfigVo.getValue());
        }
        return 0L;
    }
}
